import { MessageResultDto } from '@/gql'
import { globalModel } from '@/models/globalModel'
import { kfModel } from '@/models/KfModel'
import { ProCard } from '@ant-design/pro-components'
import { useEventTarget, useWebSocket } from 'ahooks'
import { Badge, List, Skeleton, Space, Tag } from 'antd'
import Avatar from 'antd/es/avatar/avatar'
import TextArea from 'antd/es/input/TextArea'
import { toJS } from 'mobx'
import { observer } from 'mobx-react-lite'
import { useEffect } from 'react'
import { Item, Menu, useContextMenu } from 'react-contexify'
import 'react-contexify/ReactContexify.css'
import InfiniteScroll from 'react-infinite-scroll-component'
import styled from 'styled-components'
import { SocketBO } from '../../../types/kf'
import BehaviotLabel from './component/BehaviotLabel'
import ChatToolsBar from './component/ChatToolsBar'
import ImageMessage from './component/ImageMessage'
import TextMessage from './component/TextMessage'
import style from './index.less'

const ScrollContainer = styled.div`
  height: 500px;
  overflow: auto;
`
let sendMessagez
const Message = styled.div<{ isOwnSend: boolean }>`
  /* 别人发的消息 3 */

  /* 自动布局子元素 */
  position: static;
  width: 100%;
  height: auto;

  /* 自动布局 */
  display: flex;
  flex-direction: ${(props) => (props.isOwnSend ? 'row-reverse' : 'row')};
  padding: 20px 10px;
  gap: 10px;
  align-self: stretch;
`
const KeFuMessage = (message: MessageResultDto, isOwn: boolean) => {
  let el

  if (message.messageType === 'event') {
    return <BehaviotLabel message={message} />
  }
  switch (message.messageType) {
    case 'text':
      el = <TextMessage message={message} />
      break
    case 'image':
      el = <ImageMessage message={message} />
      break
    default:
      el = <TextMessage message={message} />
  }

  return (
    <Message isOwnSend={isOwn}>
      <Avatar src={message.socialUser?.avatar} />
      {el}
    </Message>
  )
}

const MessageScrollContainer = styled(ScrollContainer)`
  display: flex;
  flex-direction: column-reverse;
`

// 会话容器
const DialogueContainer = observer(() => {
  // 右键弹窗
  const MENU_ID = ''
  const { show } = useContextMenu({
    id: MENU_ID,
  })

  function handleContextMenu(event) {
    show({
      event,
      props: {
        key: 'value',
      },
    })
  }

  const handleItemClick = ({ id, event, props }) => {
    switch (id) {
      case 'send':
        console.log(event, props)
        break
      case 'cut':
        console.log(event, props)
        break
      case 'topping':
        console.log(event, props)
        break
    }
  }

  useEffect(() => {
    kfModel.initState().then()
  }, [])
  return (
    <>
      <ScrollContainer id="dialogue-box">
        <InfiniteScroll
          next={kfModel.nextDialoguePage}
          hasMore={kfModel.hasMoreDialogue}
          loader={<Skeleton avatar paragraph={{ rows: 1 }} active />}
          dataLength={kfModel.dialogueList.length}
          // endMessage={<Divider>没有了</Divider>}
          scrollableTarget="dialogue-box"
          scrollThreshold={0.7}
        >
          <List
            split={false}
            dataSource={kfModel.dialogueList}
            renderItem={(item) => (
              <List.Item
                key={item.id}
                onClick={() => kfModel.changeCurrentDialogue(item)}
                onContextMenu={handleContextMenu}
                style={{ padding: '0px' }}
              >
                <div className={kfModel.currentDialogue?.id === item.id ? style.bga : style.content}>
                  <div className={style.img_box}>
                    <Badge count={item.unreadTotal} offset={[-5, 5]}>
                      <img className={style.headImg} src={item.user.avatar || ''} />
                    </Badge>
                  </div>
                  <div className={style.info_area}>
                    <div className={style.nickname}>
                      {item.user.nickname}
                      <div className={style.source} />
                    </div>
                    <span className={style.ordinary_vip}>会员</span>
                    <span className={style.message}>{item.lastMessage}</span>
                  </div>
                  <span className={style.update_time}>{item.updateTime}</span>
                </div>
              </List.Item>
            )}
          />
        </InfiniteScroll>
      </ScrollContainer>
      <Menu id={MENU_ID}>
        <Item id="send" onClick={handleItemClick}>
          发送消息
        </Item>
        <Item id="cut" onClick={handleItemClick}>
          删除会话
        </Item>
        <Item id="topping" onClick={handleItemClick}>
          消息置顶
        </Item>
      </Menu>
    </>
  )
})

interface MessageAreaPropsType {
  onEnterPress?: (message: string) => void
  appId: string
  openId: string
  dialogueId: string
}

function MessageArea(props: MessageAreaPropsType) {
  const [message, { onChange: setMessage }] = useEventTarget({ initialValue: '' })

  const sendMessage = () => {
    // console.log('发送消息')
    const socketDTO: SocketBO = {
      event: 'message',
      userId: globalModel.userId,
      tenantId: globalModel.tenantId,
      message: {
        appId: props.appId,
        dialogue: {
          id: props.dialogueId,
        },
        kfMessage: {
          content: message || '',
          msgType: 'text',
          toUser: props.openId,
        },
      },
    }
    sendMessagez(JSON.stringify(socketDTO))

    setTimeout(() => {
      setMessage({
        target: { value: '' },
      })
    }, 10)
  }

  const emojiSelectHandle = (emoji: string) => {
    setMessage({
      target: { value: message + emoji },
    })
  }

  return (
    <>
      <div className={style.send_box}>
        <div className={style.input_content}>
          <ChatToolsBar onEmojiSelect={emojiSelectHandle} />
          <TextArea
            onPressEnter={sendMessage}
            value={message}
            onChange={setMessage}
            placeholder="请输入..."
            autoSize={{ minRows: 5, maxRows: 6 }}
          ></TextArea>
        </div>
      </div>
    </>
  )
}

// 消息容器
const MessageContainer = observer(() => {
  return (
    <>
      <MessageScrollContainer id="message-box">
        <InfiniteScroll
          style={{
            display: 'flex',
            flexDirection: 'column-reverse',
          }} //To put endMessage and loader to the top.
          inverse={true}
          next={kfModel.nextMessagePage}
          hasMore={kfModel.hasMoreMessage}
          loader={<Skeleton avatar paragraph={{ rows: 1 }} active />}
          dataLength={kfModel.messageList.length}
          // endMessage={<Divider>没有了</Divider>}
          scrollableTarget="message-box"
          scrollThreshold={0.7}
        >
          <List
            loading={kfModel.messageLoading}
            split={false}
            dataSource={toJS(kfModel.messageList).reverse()}
            renderItem={(item) => KeFuMessage(item, globalModel.userId === item.creator)}
          />
        </InfiniteScroll>
      </MessageScrollContainer>
      {kfModel.currentDialogue && (
        <MessageArea
          appId={kfModel.currentDialogue.appId}
          dialogueId={kfModel.currentDialogue.id}
          openId={kfModel.currentDialogue.user.openid || ''}
        />
      )}
    </>
  )
})

// 页面
const KF = () => {
  // const { data, loading } = useTestQueryQuery({ variables: { dto: {} } })

  const { connect, readyState, sendMessage } = useWebSocket('wss://leuan.top/ws/kf-socket', {
    onMessage: (msg, instance) => {
      try {
        kfModel.updateDialogue(JSON.parse(msg.data))
      } catch (e) {
        console.log(e)
      }
    },
    onClose: (event, instance) => console.log('websocket链接关闭'),
  })

  useEffect(() => {
    sendMessagez = sendMessage
  }, [])
  return (
    <>
      {/* <Spin spinning={loading}>{JSON.stringify(data?.systemUserList)}</Spin> */}
      <ProCard split="vertical">
        <ProCard ghost colSpan={'387px'}>
          <DialogueContainer />
        </ProCard>
        <ProCard>
          <MessageContainer />
        </ProCard>
        <ProCard colSpan={'387px'}>
          <Space>
            {kfModel.currentDialogue?.user?.tags.map((it) => {
              return <Tag key={it.id}>{it.tagName}</Tag>
            })}
          </Space>
        </ProCard>
      </ProCard>
    </>
  )
}

export default observer(KF)
